home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / libkmid / player.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-10-08  |  10.9 KB  |  397 lines

  1. /*  player.h  - class MidiPlayer. Plays a set of tracks
  2.     This file is part of LibKMid 0.9.5
  3.     Copyright (C) 1997,98,99,2000  Antonio Larrosa Jimenez
  4.     LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html
  5.  
  6.     This library is free software; you can redistribute it and/or
  7.     modify it under the terms of the GNU Library General Public
  8.     License as published by the Free Software Foundation; either
  9.     version 2 of the License, or (at your option) any later version.
  10.  
  11.     This library is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.     Library General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU Library General Public License
  17.     along with this library; see the file COPYING.LIB.  If not, write to
  18.     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19.     Boston, MA 02110-1301, USA.                                                  
  20.  
  21.     Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
  22.  
  23. ***************************************************************************/
  24. #ifndef _PLAYER_H
  25. #define _PLAYER_H
  26.  
  27. #include <libkmid/dattypes.h>
  28. #include <libkmid/midfile.h>
  29. #include <libkmid/deviceman.h>
  30. #include <libkmid/track.h>
  31. #include <libkmid/notearray.h>
  32. #include <kdemacros.h>
  33.  
  34. /**
  35.  * This struct stores text, lyrics and change tempo events among others.
  36.  *
  37.  * It includes the main information for an event. That is, the absolute
  38.  * millisecond at which this event is played (from the beginning of the song),
  39.  * the delta milliseconds from the previous SpecialEvent, an ID, etc. 
  40.  *
  41.  * This struct is used as nodes for a linked list, which you can get using
  42.  * MidiPlayer::specialEvents().
  43.  *
  44.  * @short Struct used to store certain events
  45.  * @version 0.9.5 17/01/2000
  46.  * @author Antonio Larrosa Jimenez <larrosa@kde.org>
  47.  */
  48. struct SpecialEvent
  49. {
  50.   /**
  51.    * An integer ID, that is assigned in order to each SpecialEvent.
  52.    */
  53.   int id;
  54.  
  55.   /**
  56.    * Delta milliseconds from the previous SpecialEvent. 
  57.    *
  58.    * @see absmilliseconds
  59.    */
  60.   ulong diffmilliseconds;
  61.  
  62.   /**
  63.    * The absolute millisecond (from the beginning of the song) at which this
  64.    * SpecialEvent object is played.
  65.    *
  66.    * @see diffmilliseconds
  67.    */
  68.   ulong absmilliseconds;
  69.  
  70.   /**
  71.    * MIDI ticks (from the beginning of the song) at which this event is played.
  72.    */
  73.   int ticks;
  74.  
  75.   /**
  76.    * Type of event. This currently includes:
  77.    *
  78.    * @li 0 - Nothing, end of linked list.
  79.    * @li 1 - Text Event . See text.
  80.    * @li 3 - Change Tempo Event . See tempo.
  81.    * @li 5 - Lyrics Event . See text.
  82.    * @li 6 - Change number of beats per measure . See num and den.
  83.    * @li 7 - Beat . See num and den.
  84.    *
  85.    * The "Change number of beats per measure" and "beat" events are not really
  86.    * in the midi file, but they are added to the linked list in case you have
  87.    * an use for it.
  88.    */
  89.   int type;
  90.  
  91.   /**
  92.    * Text field . It has a meaning only for Text and Lyrics events.
  93.    */
  94.   char text[1024];
  95.  
  96.   /**
  97.    * Tempo field . It has a meaning only for Change Tempo events.
  98.    */
  99.   ulong tempo;
  100.   /**
  101.    * Numerator . It has a meaning only for Change number of beats per measure and
  102.    * beat events.
  103.    */
  104.   int num;
  105.   /**
  106.    * Denominator . It has a meaning only for Change number of beats per measure
  107.    * and beat events.
  108.    */
  109.   int den;
  110.  
  111.   /**
  112.    * This struct stores text, lyrics and change tempo events among others.
  113.    *
  114.    * It includes the main information for an event. That is, the absolute
  115.    * millisecond at which this event is played (from the beginning of the song),
  116.    * the delta milliseconds from the previous SpecialEvent, an ID, etc. 
  117.    *
  118.    * This struct is used as nodes for a linked list, which you can get using
  119.    * MidiPlayer::specialEvents().
  120.    */
  121.   struct SpecialEvent *next;
  122.  
  123.   /**
  124.    * Next node in the linked list.
  125.    */
  126.   
  127. };
  128.  
  129.  
  130. /**
  131.  * PlayerController is a struct that is used by the MidiPlayer object
  132.  * to tell other parts of the application about the status of the MIDI playing.
  133.  *
  134.  * @short Struct used to have control over the player engine
  135.  * @version 0.9.5 17/01/2000
  136.  * @author Antonio Larrosa Jimenez <larrosa@kde.org>
  137.  */
  138. struct PlayerController
  139. {
  140.   volatile ulong  ticksTotal;
  141.   volatile ulong  ticksPlayed;
  142.   volatile double millisecsPlayed;
  143.   volatile ulong  beginmillisec;
  144.  
  145.   volatile int tempo;
  146.   volatile int num;
  147.   volatile int den;
  148.  
  149.   volatile int SPEVprocessed;
  150.   volatile int SPEVplayed;
  151.  
  152.   /**
  153.    * When pause is released, if the caller must know when the player has
  154.    * opened the devices and is playing again, then it just has to check
  155.    * to see when OK changes the value to 1
  156.    */
  157.   volatile int OK; 
  158.  
  159.   /**
  160.    * When the player is playing (or paused), playing is set to 1.
  161.    */
  162.   volatile int playing;
  163.  
  164.   /**
  165.    * When the player is paused, paused is set to 1.
  166.    */
  167.   volatile int paused;
  168.  
  169.   /**
  170.    * When the player seeking the position of the song, moving is set to 1.
  171.    */
  172.   volatile int moving;
  173.  
  174.   /**
  175.    * When the player has finished playing a song, finished is set to 1.
  176.    */
  177.   volatile int finished;
  178.  
  179.   /**
  180.    * @internal
  181.    * @deprecated
  182.    * Not used
  183.    */
  184.   volatile int message KDE_DEPRECATED; // set one of the following :
  185.  
  186. #define PLAYER_DOPAUSE    1
  187. #define PLAYER_DOSTOP    2
  188. #define PLAYER_SETPOS    4
  189. #define PLAYER_HALT    8
  190.  
  191.   volatile ulong gotomsec; //milliseconds to go to,if player_setpos is set
  192.  
  193.   /**
  194.    * When error is 1, an error has ocurred (i.e. it coultn't open the device)
  195.    */    
  196.   volatile int error;
  197.  
  198.   /**
  199.    * If gm is 1, the song follows the General Midi standard, if gm is 0, the song
  200.    * is in MT 32 format.
  201.    */
  202.   volatile int gm;
  203.  
  204.   /**
  205.    * 100 means no change, 50 halfs the volume, 200 doubles it (if possible), etc.
  206.    *
  207.    * @see DeviceManager::setVolumePercentage()
  208.    */
  209.   volatile int volumepercentage ; 
  210.  
  211.   /**
  212.    * Activate or disactivate the force to use a patch for a given channel.
  213.    * @see pgm
  214.    */
  215.   volatile bool forcepgm[16];
  216.  
  217.   /**
  218.    * Force a given patch in each channel at "this" moment, as determined by
  219.    * forcepgm.
  220.    */
  221.   volatile int pgm[16];
  222.  
  223.   /**
  224.    * Ratio to multiply the tempo to.
  225.    */
  226.   volatile double ratioTempo;
  227.  
  228.   /**
  229.    * @internal Used to stop the main pid until the child has finished to 
  230.    * send the all notes off event
  231.    */
  232.   volatile bool isSendingAllNotesOff;
  233.  
  234.   volatile MidiEvent *ev;
  235. };
  236.  
  237.  
  238. /**
  239.  * MIDI file player routines . This class reads a MIDI file and
  240.  * play it using a DeviceManager object.
  241.  *
  242.  * To use it, just call loadSong() with the filename you want to play,
  243.  * and then play().
  244.  * 
  245.  * Please have a look at the note in the play() documentation.
  246.  *
  247.  * MidiPlayer will write information about the playing process on a 
  248.  * PlayerController() structure that you must supply to the constructor
  249.  *
  250.  * Alternatively, if everything you want is to play a midi file in a game or
  251.  * any other application that doesn't need to fine tune the midi playing, just
  252.  * use the kmidplay() function.
  253.  *
  254.  * @see KMidSimpleAPI
  255.  *
  256.  * @short The MIDI file player engine
  257.  * @version 0.9.5 17/01/2000
  258.  * @author Antonio Larrosa Jimenez <larrosa@kde.org>
  259.  */
  260. class KMID_EXPORT MidiPlayer
  261. {
  262.   class MidiPlayerPrivate;
  263.   MidiPlayerPrivate *d;
  264.  
  265.   DeviceManager *midi;
  266.   MidiFileInfo *info;
  267.   MidiTrack **tracks;
  268.   SpecialEvent *spev;
  269.   NoteArray *na;
  270.  
  271.   int songLoaded;
  272.  
  273.   PlayerController *ctl;
  274.  
  275.   bool parsesong;
  276.   bool generatebeats;
  277.  
  278.   void removeSpecialEvents(void);
  279.   void parseSpecialEvents(void);
  280.   void insertBeat(SpecialEvent *ev,ulong ms,int num,int den);
  281.   void generateBeats(void);
  282.  
  283.   //NoteArray *parseNotes(void);
  284.   void debugSpecialEvents(void);
  285.   public:
  286.  
  287.   /**
  288.    * Constructor . You must construct and pass a DeviceManager object and a 
  289.    * PlayerController structure. None of them will be destroyed by this
  290.    * object, so you should do it after destroying the MidiPlayer object.
  291.    */
  292.   MidiPlayer(DeviceManager *midi_,PlayerController *pctl);
  293.  
  294.   /**
  295.    * Destructor.
  296.    */
  297.   ~MidiPlayer();
  298.  
  299.   /**
  300.    * Loads a Song, and parses it (it the parse wasn't disabled with 
  301.    * setParseSong() ) . It also generates the Beat events (see 
  302.    * SpecialEvent::type() ) if you enabled this by using 
  303.    * setGenerateBeats() .
  304.    */
  305.   int loadSong(const char *filename);
  306.  
  307.   /**
  308.    * Unloads the current song, so that every internal variable is empty and clean
  309.    * for further usage.
  310.    */
  311.   void removeSong(void); 
  312.  
  313.   /**
  314.    * Returns true if there's a song already loaded (with a previous call to 
  315.    * loadSong() ) and false if not.
  316.    */
  317.   int isSongLoaded(void) { return songLoaded; }
  318.  
  319.   /**
  320.    * Returns the linked list of SpecialEvents objects . For this to work,
  321.    * the parse should be enabled (the default), by using setParseSong().
  322.    */
  323.   SpecialEvent *specialEvents() { return spev; }
  324.  
  325.   /**
  326.    * Returns and array with the notes playen through the song . MidiPlayer must
  327.    * parse the song to get the notes, so be sure not to disable the parsing of
  328.    * the song.
  329.    *
  330.    * Returns an array of notes, (just note on and note off events), in the form
  331.    * of a NoteArray object
  332.    */
  333.   NoteArray *noteArray(void) { return na; }
  334.  
  335.  
  336.   /**
  337.    * Plays the song using the DeviceManager object supplied in the
  338.    * constructor. It should be already configured, as play doesn't change the
  339.    * volume, nor midi mapper, for example.
  340.    *
  341.    * Note: Calling this function will block the execution of your application
  342.    * until the song finishes playing. The solution for this is simple, fork
  343.    * before calling it, and create the PlayerController object on shared
  344.    * memory.
  345.    *
  346.    * As alternative, if everything you want is playing a midi file in a game or
  347.    * any other application that doesn't need to fine tune the midi playing, just
  348.    * use the KMidSimpleAPI::kMidPlay() function. 
  349.    *
  350.    * @see KMidSimpleAPI::kMidInit
  351.    * @see KMidSimpleAPI::kMidPlay
  352.    * @see KMidSimpleAPI::kMidStop
  353.    * @see KMidSimpleAPI::kMidDestruct
  354.    */
  355.   void play(bool calloutput=false,void output(void) = 0);
  356.  
  357.   /**
  358.    * Enables or disables the parsing of the song when loading it. This affects
  359.    * the SpecialEvents ( specialEvents() ) and the NoteArray 
  360.    * ( noteArray() ).
  361.    */
  362.   void setParseSong(bool b = true);
  363.  
  364.   /**
  365.    * Enables or disables the generation of beats event in a song when loading
  366.    * it. 
  367.    */
  368.   void setGenerateBeats(bool b = false);
  369.  
  370.   /**
  371.    * Returns information about the current MIDI file.
  372.    *
  373.    * @see loadSong
  374.    */
  375.   MidiFileInfo *information(void) { return info; }
  376.  
  377.   /**
  378.    * Sets the position in a song. 
  379.    * @param gotomsec the number of milliseconds to go to . A subsequent call to
  380.    * play() will start playing the song from that moment, instead of the
  381.    * beginning.
  382.    * @param midistat a MidiStatus object that will contain the status in
  383.    * which the MIDI device would be if it would have arrived to this situation by
  384.    * a normal playing of the song.
  385.    */
  386.   void setPos(ulong gotomsec, class MidiStatus *midistat);
  387.  
  388.   /**
  389.    * Changes the speed at which a song is played. The song's tempo is multiplied
  390.    * by the specified ratio.
  391.    */
  392.   void setTempoRatio(double ratio);
  393.  
  394. };
  395.  
  396. #endif
  397.